import pandas as pd
from utils.trendline import fit_trend_line
from core.signals import generate_signals


class DowTheoryAnalyzer:
    def __init__(self, window_primary=30, window_secondary=10, volume_threshold=1.2):
        self.window_primary = window_primary
        self.window_secondary = window_secondary
        self.volume_threshold = volume_threshold
        self.data = None
        self.trend_lines = {
            'primary_up': None,
            'primary_down': None
        }
        self.signals = None

    def analyze(self, data):
        """执行完整分析流程"""
        self.data = data.copy()
        self._identify_key_points()
        self._fit_trend_lines()
        self.signals = generate_signals(
            data=self.data,
            trend_lines=self.trend_lines,
            volume_threshold=self.volume_threshold
        )
        return self

    def _identify_key_points(self):
        """识别关键点位（带成交量确认）"""
        # 主要趋势
        self.data['Primary_High'] = self.data['Close'].rolling(
            window=self.window_primary, min_periods=1).max()
        self.data['Primary_Low'] = self.data['Close'].rolling(
            window=self.window_primary, min_periods=1).min()

        # 标记确认的关键点
        self.data['Primary_Peak'] = (
                (self.data['Close'] == self.data['Primary_High']) &
                (self.data['Volume'] > self.volume_threshold * self.data['Volume_MA'])
        )
        self.data['Primary_Valley'] = (
                self.data['Close'] == self.data['Primary_Low']
        )

    def _fit_trend_lines(self):
        """拟合主要趋势线"""
        # 获取确认的关键点
        primary_peaks = self.data[self.data['Primary_Peak']]
        primary_valleys = self.data[self.data['Primary_Valley']]

        # 拟合上升趋势线（连接两个主要波谷）
        if len(primary_valleys) >= 2:
            valleys = primary_valleys.tail(2)
            self.trend_lines['primary_up'] = fit_trend_line(valleys['Close'])

        # 拟合下降趋势线（连接两个主要波峰）
        if len(primary_peaks) >= 2:
            peaks = primary_peaks.tail(2)
            self.trend_lines['primary_down'] = fit_trend_line(peaks['Close'])

